package com.zodiac.app.szse.e.e0201.e020101;

import com.alibaba.fastjson.JSONArray;
import com.github.lzm320a99981e.component.dataautomation.AbstractExtractor;
import com.github.lzm320a99981e.component.office.excel.SimpleExcelReader;
import lombok.Data;
import org.jsoup.Jsoup;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.io.ByteArrayInputStream;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 深圳证券交易所 >> 市场数据 >> 上市公司 >> 上市公司列表
 *
 * @link {http://www.szse.cn/market/companys/company/index.html}
 */
@Component
public class E020101Extractor extends AbstractExtractor<E020101Extractor.Request, List<E020101Model>> {
    private final RestTemplate restTemplate = new RestTemplate();

    @Override
    public List<E020101Model> extract(Request request) {
        if (request.getShowType() == E020101ShowType.JSON) {
            JSONArray response = restTemplate.getForObject(request.getUrl(), JSONArray.class);
            if (Objects.isNull(response)) {
                return null;
            }
            List<Map<String, String>> data = (List<Map<String, String>>) response.stream().map(item -> ((Map) item).get("data")).filter(item -> !((List) item).isEmpty()).findFirst().orElse(null);
            if (Objects.isNull(data)) {
                return null;
            }

            final E020101Board board = request.getBoard();
            return data.stream().map(item -> {
                final E020101Model model = new E020101Model();
                model.setAstockCode(item.get("zqdm"));
                String gsjc = Jsoup.parse(item.get("gsjc")).text().trim();
                model.setAstockName(gsjc);
                model.setCompanyShortName(gsjc);
                model.setCompanyName(item.get("gsqc"));
                model.setCompanyWebsite(item.get("http"));
                model.setIndustry(item.get("sshymc"));
                model.setBoard(board);
                return model;
            }).collect(Collectors.toList());
        }

        return readXlsx(request);
    }


    public int count(Request request) {
        if (request.getShowType() == E020101ShowType.JSON) {
            JSONArray response = restTemplate.getForObject(request.getUrl(), JSONArray.class);
            for (int i = 0; i < response.size(); i++) {
                if (!response.getJSONObject(i).getJSONArray("data").isEmpty()) {
                    return response.getJSONObject(i).getJSONObject("metadata").getIntValue("recordcount");
                }
            }
            return 0;
        }
        return readXlsx(request).size();
    }

    private List<E020101Model> readXlsx(Request request) {
        HttpEntity<Object> entity = new HttpEntity<>(new HttpHeaders());
        byte[] body = restTemplate.exchange(request.getUrl(), HttpMethod.GET, entity, byte[].class).getBody();
        List<E020101Model> models = SimpleExcelReader.create().readTable(E020101Model.class, new ByteArrayInputStream(body));
        models.forEach(item -> item.setBoard(request.getBoard()));
        return models;
    }

    @Data
    public static class Request {
        private E020101Board board;
        private E020101ShowType showType;
        private int pageno = 1;

        public Request(E020101Board board, E020101ShowType showType) {
            this.board = board;
            this.showType = showType;
        }

        public static Request create(E020101Board board, E020101ShowType showType) {
            return new Request(board, showType);
        }

        public String getUrl() {
            if (E020101ShowType.JSON == showType) {
                return "http://www.szse.cn/api/report/ShowReport/data?CATALOGID=1110x&PAGENO=" + pageno + "&SHOWTYPE=JSON&TABKEY=" + board.getValue() + "&random=" + Math.random();
            }
            return "http://www.szse.cn/api/report/ShowReport?SHOWTYPE=xlsx&CATALOGID=1110x&TABKEY=" + board.getValue() + "&random=" + Math.random();
        }
    }

}
